package com.wstuo.common.dao;

import java.io.Serializable;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.wstuo.common.dto.PageDTO;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;

/**
 * BaseDAO Impl JpaDaoSupport
 * @author Will
 *
 * @param <T>
 */
public abstract class BaseDAOImplJPA<T> extends JpaDaoSupport
    implements IEntityDAO<T> {

    protected Class<T> entityClass = null;

    public BaseDAOImplJPA() {

        Type t = getClass().getGenericSuperclass();

        if (t instanceof ParameterizedType) {

            entityClass = (Class<T>) ((ParameterizedType) t)
                .getActualTypeArguments()[0];
        }
    }

    public void save(T entity) {

        getJpaTemplate().persist(entity);
    }

    public void delete(T entity) {

        getJpaTemplate().remove(entity);
    }

    public void update(T entity) {

        save(entity);
    }

    public T merge(T entity) {

        return getJpaTemplate().merge(entity);
    }

    public T findById(Serializable id) {

        return getJpaTemplate().find(entityClass, id);
    }

    public List<T> findAll() {

        return getJpaTemplate().find("from " + entityClass.getName());
    }

    public void deleteAll() {

        deleteAll(findAll());
    }

    public void deleteAll(Collection<T> entities) {

        for (T entity : entities) {

            delete(entity);
        }
    }

    public void updateAll(Collection<T> entities) {

        for (T entity : entities) {

            update(entity);
        }
    }

    public Collection mergeAll(Collection<T> entities) {

        Collection<T> ets = new ArrayList<T>();

        for (T entity : entities) {

            ets.add(merge(entity));
        }

        return ets;
    }

    public List findBy(String propertyName, Object value) {

        // TODO Auto-generated method stub
        return null;
    }

    public List findBy(String propertyName, Object value, String orderBy,
        boolean isAsc) {

        // TODO Auto-generated method stub
        return null;
    }

    public T findById(Serializable id, boolean lock) {

        // TODO Auto-generated method stub
        return null;
    }
    public T loadById( Serializable id )
    {
    	return null;
    }
    public T findUniqueBy(String propertyName, Object value) {

        // TODO Auto-generated method stub
        return null;
    }

    protected PageDTO findPager(final String ql1, final String ql2,
        final int start, final int limit) {

        PageDTO p = (PageDTO) getJpaTemplate().execute(new JpaCallback<PageDTO>() {

                    public PageDTO doInJpa(EntityManager em) {

                        Query q1 = em
                            .createQuery(ql1);
                        Integer totalSize = ((Number) q1.getSingleResult())
                            .intValue();
                        Query q2 = em.createQuery(ql2);

                        q2.setFirstResult(start);
                        q2.setMaxResults(limit);

                        PageDTO p = new PageDTO();

                        p.setTotalSize(totalSize);
                        p.setData(q2.getResultList());
                        p.getData().size();

                        return p;
                    }
                });

        return p;
    }

    public void deleteByIds(Serializable[] ids) {

    }

    public void purge(T entity) {
    	
    }
}